﻿#include "CClientListenerModule.h"
#include "CSocketMisc.h"
#include "CMsg.h"
#include "../game/MsgID.h"
#include "../game/MsgStruct.h"

#include <string.h>
#include <stdio.h>
#include <process.h>
#include <Ws2tcpip.h>

#pragma warning(disable:4996)

#define DEBUG_LOG printf
#define RCV_BUFF_SIZE 2048

static void lisenProc(void* param) {
	CClientListenerModule* thes = (CClientListenerModule*)param;
	WSANETWORKEVENTS wsaEvents;
	char buf[RCV_BUFF_SIZE] = {0};
	int readSize = 0;
	int nowIdx = 0;
	CModule* e = thes->msg_executer;

	while (1) {
		WSAWaitForMultipleEvents(1, &thes->mEvent, FALSE, WSA_INFINITE, FALSE);
		WSAEnumNetworkEvents(thes->mSocket, thes->mEvent, &wsaEvents);
		if (0 == (wsaEvents.lNetworkEvents & FD_READ)) {
			continue;
		}
		if (0 != wsaEvents.iErrorCode[FD_READ_BIT]) {
			continue;
		}

		nowIdx = 0;
		memset(buf, 0, RCV_BUFF_SIZE);
		readSize = recv(thes->mSocket, buf, RCV_BUFF_SIZE, 0);
		while (nowIdx != readSize) {
			CMsg* msg = (CMsg*)(&buf[nowIdx]);
			nowIdx += (msg->data_len + sizeof(CMsg));
			e->sendMsg(e, msg);
		}
	}

	closesocket(thes->mSocket);
	WSACleanup();
	return;
}

static int connect_server(struct _cclientlistener_module_* thes) {
	WSADATA              wsaData;
	SOCKADDR_IN          ServerAddr;
	ST_NOTIFY_CLIENT_SOCKET notify = {{MSG_ID_NOTIFY_CLIENT_SOCKET, sizeof(notify) - sizeof(CMsg)}, 0};

	thes->mEvent = WSACreateEvent();
	WSAStartup(MAKEWORD(2, 2), &wsaData);
	thes->mSocket = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
	ServerAddr.sin_family = AF_INET;
	ServerAddr.sin_port = htons(thes->port);
	ServerAddr.sin_addr.s_addr = inet_addr(thes->server_ip);
	if (SOCKET_ERROR == connect(thes->mSocket, (SOCKADDR *)&ServerAddr, sizeof(ServerAddr))) {
		printf("connect server failed. err code=%d\n", WSAGetLastError());
		return -1;
	}
	WSAEventSelect(thes->mSocket, thes->mEvent, FD_ACCEPT | FD_CLOSE | FD_READ);
	_beginthread(lisenProc, 0, thes);

	notify.sock = thes->mSocket;
	thes->msg_executer->sendMsg(thes->msg_executer, &notify.msg);
	return 0;
}

static int send_msg_to_server(CClientListenerModule* thes, CMsg* msg) {
	csocketmisc_send_msg(&thes->mSocket, msg);
	return 0;
}

int construct_client_listener(CClientListenerModule* thes, const char* module_name, const char* server_ip, unsigned short port, CModule* msg_executer) {
	construct_module(&thes->parent, module_name);
	thes->msg_executer = msg_executer;
	memcpy(thes->server_ip, server_ip, sizeof(thes->server_ip));
	thes->port = port;
	thes->connect_server = connect_server;
	thes->send_msg_to_server = send_msg_to_server;
	AS_MODULE(thes)->run(AS_MODULE(thes), USE_DEFAULT_MODULE_ENTRY);
	return 0;
}

